---
title: Locks and Concurrency
description: Manage concurrent Terraform operations and prevent conflicts
---

import MermaidDiagram from '../../../../components/MermaidDiagram.astro';
import { Card, LinkCard, CardGrid } from '@astrojs/starlight/components';

Terrateam's locks and concurrency feature ensures that changes to your infrastructure are safely applied by preventing concurrent modifications to the same resources. Locks guarantee that only a single change to a resource can be applied in a pull request at any given time, avoiding conflicts and maintaining consistency between your Terraform configuration and the real-world state of your infrastructure.

## Why are locks important?  
Suppose Alice and Bob both open pull requests that modify the same Terraform resource. Without locks, both could apply their changes independently, leading to a situation where the real infrastructure state no longer matches the code in your main branch. Locks prevent this by ensuring only one change can be applied at a time.

<MermaidDiagram chart={`
flowchart TD
    T1["Alice"] --> A1["Alice PR<br>plan"]
    T2["Bob"] --> B1["Bob PR<br>plan"]

    A2["Alice PR<br>apply (acquire lock)"]
    A3["Alice PR<br>infra update"]
    A4["Alice PR<br>release lock"]

    B2["Bob PR<br>apply (blocked)"]
    B3["Bob PR<br>re-plan"]
    B4["Bob PR<br>apply (acquire lock)"]
    B5["Bob PR<br>infra update"]
    B6["Bob PR<br>release lock"]

    A1 --> A2 --> A3 --> A4 --> B3
    B1 --> B2
    B3 --> B4 --> B5 --> B6
`} />

## Concurrent Collaboration

When multiple team members are working on the same Terraform project, locks play a crucial role in coordinating their efforts and preventing conflicting changes.

<CardGrid>
  <Card title="Coordination">
    When a team member applies a change to a resource in a pull request, Terrateam acquires a lock on that resource. This lock ensures that no other team member can concurrently apply changes to the same resource, preventing conflicts and inconsistencies.
  </Card>
  <Card title="Invalidation">
    If a team member attempts to apply a change to a resource that is already locked by another apply operation, Terrateam will deny the change. Once the lock is released, the change can be re-planned and applied.
  </Card>
  <Card title="Consistency">
    By preventing concurrent modifications to the same resources, locks help maintain consistency between your Terraform configuration and the actual state of your infrastructure.
  </Card>
</CardGrid>

## What is a Lock?

A lock is a mechanism that ensures only a single change to a resource can be applied in a pull request at any given time. When a lock is acquired on a resource, changes to that resource in other pull requests cannot be concurrently applied.

:::note
- A lock is owned by a pull request.
- A lock applies to the [dirspace](/getting-started/concepts#dirspace) (a combination of a directory and a workspace).
:::

## When is a Lock Acquired?

By default, a lock is acquired when executing an apply operation or merging a pull request without applying the changes. The lock is acquired on the dirspaces targeted in the pull request.

:::note
- A lock is acquired regardless of the success or failure of an apply.
- Once a single dirspace has been applied in a pull request, that pull request owns locks on all targeted dirspaces associated with the pull request.
- A lock is only released after a successful apply and merge.
- A lock can be forcefully unlocked by commenting `terrateam unlock` on the pull request.
:::

## When is a Lock Not Acquired?

If a pull request is created but never applied or merged, no lock is acquired. Locks are only acquired when executing an apply or merging a pull request without applying the changes.

### Example: Locking in Action

Consider a pull request with changes in `dir1` and `dir2` (using only the `default` workspace):

<MermaidDiagram chart={`
flowchart TD
    PR["PR opened: changes in <br>dir1, dir2"]
    Plan["terrateam plan"]
    Apply["terrateam apply dir:dir1"]
    Locks["Locks acquired: <br>(dir1, default), (dir2, default)"]
    PR --> Plan --> Apply --> Locks
`} />

The pull request now owns locks on the following dirspaces:
- `(dir1, default)`
- `(dir2, default)`

## When is a Lock Released?

A lock is released when a change has been both applied and merged.

## Unlocking

In certain scenarios, you may want to force an unlock. To explicitly remove a lock, comment `terrateam unlock` in the pull request that owns the lock.

:::info
- Executing `terrateam unlock` only applies to locks acquired prior to performing the unlock.
- Performing a merge or `apply` after an `unlock` will acquire any necessary locks again.
:::

:::caution
The `terrateam unlock` command is very powerful.
- Executing this command will unlock all locks in the pull request.
- If `terrateam apply` is issued in multiple pull requests, Terrateam will ensure that only a single apply is executed.
- If `terrateam unlock` is issued during an in-flight apply operation, Terrateam will unlock all locks in the pull request and subsequently allow an additional apply operation in a separate pull request. If both pull requests have changes against the same set of Terraform resources, the additional apply could result in unintended consequences.

*With great power comes great responsibility*
:::

## Locking Policies

The `lock_policy` option under workflows in your Terrateam configuration file instructs Terrateam under what situations it should acquire a lock.

| Policy   | Description                                                                                                         | Recommended Use Case                |
|----------|---------------------------------------------------------------------------------------------------------------------|-------------------------------------|
| `strict` | Acquire a lock if a user comments `terrateam apply` or the change is merged. Lock is released when the other action is performed. | Production environments (default)   |
| `apply`  | Acquire a lock only if the directory has been applied in Terrateam. Lock is released once the change is merged.     | Standard apply/merge workflows      |
| `merge`  | Acquire a lock only if the directory has been merged. Lock is released when the change is applied.                  | Dev/playground branches             |
| `none`   | Never acquire a lock.                                                                                               | Special cases, not recommended      |

## Best Practices

When working with locks in a team environment, consider the following best practices:
- Communicate and coordinate with your team members when working on shared resources to avoid conflicts and delays.
- Regularly review the lock status and address any long-standing locks that may be blocking other team members' progress.
- If necessary, use Terrateam's override mechanisms (e.g., `terrateam unlock`) judiciously and with caution, ensuring that all team members are aware of the implications.
- Establish clear guidelines and processes within your team for managing locks, resolving conflicts, and ensuring smooth collaboration.
